package com.yn.sample.execution.objectfactory;

import com.yn.sample.execution.memory.MemoryManagement;
import lombok.Data;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StringUtils;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.nio.ByteBuffer;
import java.util.Map;

@Data
public class MethodInterceptorForCustomObject implements MethodInterceptor {

    private CustomObject customObject;

    public MethodInterceptorForCustomObject(CustomObject customObject) {
        this.customObject = customObject;
    }


    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Method method = invocation.getMethod();

        /**
         * 获取字段的名称
         */
        String methodName = method.getName();
        String fieldName = null;
        if (methodName.startsWith("get")) {
            String s = methodName.substring("get".length());
            fieldName = StringUtils.uncapitalize(s);

            return getFieldValue(fieldName);
        } else if (methodName.startsWith("set")) {
            String s = methodName.substring("set".length());
            fieldName = StringUtils.uncapitalize(s);

            Object argument = invocation.getArguments()[0];
            return setFieldValue(fieldName,argument);
        }

        return null;
    }

    private Object getFieldValue(String fieldName) {
        /**
         * 获取该对象的内存空间
         */
        ObjectInfo objectInfo = customObject.getObjectInfo();
        ByteBuffer eden = objectInfo.getEden();
        int objectOffsetInByteBuffer = objectInfo.getObjectOffsetInByteBuffer();


        /**
         * 获取该field的offset
         */
        CustomObjectHeader header = customObject.getHeader();
        ClassInfo classInfo = header.getClassInfo();
        Map<String, FieldInfo> fieldInfoMap = classInfo.getFieldInfoMap();
        FieldInfo fieldInfo = fieldInfoMap.get(fieldName);
        if (fieldInfo == null) {
            throw new RuntimeException();
        }
        Integer fieldOffset = fieldInfo.getFieldOffset();
        Class<?> fieldType = fieldInfo.getField().getType();

        /**
         * 根据offset、field 类型、及内存，获取对应的field
         */
        Object fieldValue = MemoryManagement.getFieldValueFromMemory(objectOffsetInByteBuffer,fieldOffset,fieldType);

        return fieldValue;
    }



    private Object setFieldValue(String fieldName,Object value) {
        /**
         * 获取该对象的内存空间
         */
        ObjectInfo objectInfo = customObject.getObjectInfo();
        ByteBuffer eden = objectInfo.getEden();
        int objectOffsetInByteBuffer = objectInfo.getObjectOffsetInByteBuffer();


        /**
         * 获取该field的offset
         */
        CustomObjectHeader header = customObject.getHeader();
        ClassInfo classInfo = header.getClassInfo();
        Map<String, FieldInfo> fieldInfoMap = classInfo.getFieldInfoMap();
        FieldInfo fieldInfo = fieldInfoMap.get(fieldName);
        if (fieldInfo == null) {
            throw new RuntimeException();
        }
        Integer fieldOffset = fieldInfo.getFieldOffset();
        Class<?> fieldType = fieldInfo.getField().getType();

        /**
         * 根据offset、field 类型、及内存，获取对应的field
         */
        MemoryManagement.setFieldValue2Memory(objectOffsetInByteBuffer,
                fieldOffset,
                fieldType,
                value);

        return null;
    }
}
